package com.gy.def.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.gy.def.dataobject.CourseTable;
import com.gy.def.dataobject.UserTable;
import com.gy.def.enums.ResultEnum;
import com.gy.def.exception.GySchoolException;
import com.gy.def.service.CourseService;
import com.gy.def.service.UserService;
import com.gy.def.utils.ResultVoUtil;
import com.gy.def.viewobject.ResultVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@CrossOrigin // 允许跨域
@Api(value = "AppUserController", description = "用户模块")
@RestController
@RequestMapping("/user")
public class UserController {

  @Autowired
  private CourseService courseService;

  @Autowired
  private UserService appUserService;

  @ApiOperation(value = "用户登录", notes = "用户登录")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "password", value = "密码", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "userType", value = "用户类型", required = true, dataType = "int")
  })
  @PostMapping("/login")
  public ResultVo<UserTable> login(@RequestParam("username") String username, @RequestParam("password") String password,
                                   @RequestParam("username") int userType) {
    UserTable userTable = appUserService.findByUserNameAndUserPwdAndUserType(username, password, userType);

    if (userTable == null) {
      return ResultVoUtil.error(ResultEnum.ErrorAccountOrPassword.getCode(), ResultEnum.ErrorAccountOrPassword.getMessage());
    }

    return ResultVoUtil.success(userTable);
  }

  @ApiOperation(value = "用户注册", notes = "用户注册")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "password", value = "密码", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "userMail", value = "邮箱", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "userNick", value = "昵称", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "userType", value = "类型", required = true, dataType = "string"),
  })
  @PostMapping("/register")
  public ResultVo register(@RequestParam("username") String username, @RequestParam("userMail") String userMail, @RequestParam("password") String userPwd,
                           @RequestParam("userNick") String userNick, @RequestParam("userType") int userType) {
    UserTable userTable = appUserService.findByUserName(username);
    if (userTable != null) {
      return ResultVoUtil.error(ResultEnum.ErrorAccountRepetition.getCode(), ResultEnum.ErrorAccountRepetition.getMessage());
    }

    UserTable au = new UserTable();
    String uid = UUID.randomUUID().toString();
    au.setUserId(uid);
    au.setUserType(userType);
    au.setUserNick(userNick);
    au.setUserPwd(userPwd);
    au.setUserMail(userMail);
    au.setUserName(username);

    appUserService.save(au);
    return ResultVoUtil.success();
  }

  @ApiOperation(value = "用户忘记密码", notes = "用户忘记密码")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "userMail", value = "账户邮箱", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "password", value = "新密码", required = true, dataType = "string")
  })
  @PostMapping("/forgetPassword")
  public ResultVo forgetPassword(@RequestParam("userMail") String userMail, @RequestParam("username") String username, @RequestParam("password") String password) {
    UserTable userTable = appUserService.findByUserName(username);
    if (userTable == null) {
      return ResultVoUtil.error(ResultEnum.GetUserAccountNULL.getCode(), ResultEnum.GetUserAccountNULL.getMessage());
    }

    if (!userTable.getUserMail().equals(userMail)) {
      return ResultVoUtil.error(ResultEnum.ErrorVerifyMailbox.getCode(), ResultEnum.ErrorVerifyMailbox.getMessage());
    }

    userTable.setUserPwd(password);
    appUserService.save(userTable);

    return ResultVoUtil.success();
  }

  @ApiOperation(value = "用户修改昵称", notes = "用户修改昵称")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "nickname", value = "昵称", required = true, dataType = "string"),
  })
  @PostMapping("/modifyUserNickName")
  public ResultVo modifyUserNickName(@RequestParam("username") String username, @RequestParam("nickname") String nickname) {
    UserTable userTable = appUserService.findByUserName(username);
    if (userTable == null) {
      return ResultVoUtil.error(ResultEnum.GetUserAccountNULL.getCode(), ResultEnum.GetUserAccountNULL.getMessage());
    }

    userTable.setUserNick(nickname);
    appUserService.save(userTable);

    return ResultVoUtil.success();
  }

  @ApiOperation(value = "用户修改密码", notes = "用户修改密码")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "password", value = "密码", required = true, dataType = "string"),
  })
  @PostMapping("/modifyUserPassword")
  public ResultVo modifyUserPassword(@RequestParam("username") String username, @RequestParam("password") String password) {
    UserTable userTable = appUserService.findByUserName(username);
    if (userTable == null) {
      return ResultVoUtil.error(ResultEnum.GetUserAccountNULL.getCode(), ResultEnum.GetUserAccountNULL.getMessage());
    }

    userTable.setUserPwd(password);
    UserTable result = appUserService.save(userTable);

    if (result == null) {
      throw new GySchoolException(ResultEnum.FAIL.getCode(), ResultEnum.FAIL.getMessage());
    }

    return ResultVoUtil.success();
  }

  @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "string"),
  })
  @PostMapping("/getUserInfo")
  public ResultVo<UserTable> getUserInfo(@RequestParam("username") String username) {
    UserTable userTable = appUserService.findByUserName(username);
    if (userTable == null) {
      return ResultVoUtil.error(ResultEnum.GetUserAccountNULL.getCode(), ResultEnum.GetUserAccountNULL.getMessage());
    }

    return ResultVoUtil.success(userTable);
  }

  @ApiOperation(value = "设置用户费用", notes = "设置用户费用")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "eleMoney", value = "用户缴电费", required = true, dataType = "float"),
    @ApiImplicitParam(paramType = "query", name = "studyMoney", value = "用户缴学费", required = true, dataType = "float"),
    @ApiImplicitParam(paramType = "query", name = "realMoney", value = "用户缴重修费", required = true, dataType = "float"),
  })
  @PostMapping("/setUserMoney")
  public ResultVo setUserMoney(@RequestParam("username") String username,
                               @RequestParam("eleMoney") float eleMoney,
                               @RequestParam("studyMoney") float studyMoney,
                               @RequestParam("realMoney") float realMoney) {
    UserTable userTable = appUserService.findByUserName(username);
    if (userTable == null) {
      return ResultVoUtil.error(ResultEnum.GetUserAccountNULL.getCode(), ResultEnum.GetUserAccountNULL.getMessage());
    }

    userTable.setUserPayMoneyEle(eleMoney);
    userTable.setUserPayMoneyReal(realMoney);
    userTable.setUserPayMoneyStudy(studyMoney);

    UserTable result = appUserService.save(userTable);

    if (result == null) {
      throw new GySchoolException(ResultEnum.FAIL.getCode(), ResultEnum.FAIL.getMessage());
    }

    return ResultVoUtil.success();
  }

  @ApiOperation(value = "选课", notes = "选课")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "courseId", value = "课程id", required = true, dataType = "string"),
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "float")
  })
  @PostMapping("/selectCourse")
  private ResultVo selectCourse(@RequestParam("courseId") String courseId,
                                @RequestParam("username") String username) {
    CourseTable ct = courseService.findByCourseId(courseId);
    if (ct == null) {
      throw new GySchoolException(ResultEnum.ErrorCourseNull);
    }

    UserTable ut = appUserService.findByUserName(username);
    if (ut == null) {
      throw new GySchoolException(ResultEnum.GetUserAccountNULL);
    }

    JSONArray courseList;

    if (ut.getUserCourseList() != null) {
      courseList = JSON.parseArray(ut.getUserCourseList());
      if (courseList.contains(courseId)) {
        throw new GySchoolException(ResultEnum.AlreadyAddCourse);
      }
    } else {
      courseList = new JSONArray();
    }

    courseList.add(courseId);

    ut.setUserCourseList(courseList.toJSONString());
    appUserService.save(ut);

    ct.setCourseCount(ct.getCourseCount() + 1);
    courseService.save(ct);

    return ResultVoUtil.success();
  }

  @ApiOperation(value = "获取我的课程", notes = "获取我的课程")
  @ApiImplicitParams({
    @ApiImplicitParam(paramType = "query", name = "username", value = "账户", required = true, dataType = "float")
  })
  @PostMapping("/getMyCourse")
  private ResultVo<List<CourseTable>> getMyCourse(@RequestParam("username") String username) {
    UserTable ut = appUserService.findByUserName(username);
    if (ut == null) {
      throw new GySchoolException(ResultEnum.GetUserAccountNULL);
    }

    List<CourseTable> courseList = new ArrayList<>();
    if (ut.getUserCourseList() != null) {
      JSONArray courseArr = JSON.parseArray(ut.getUserCourseList());
      for (Object obj : courseArr) {
        CourseTable ct = courseService.findByCourseId(obj.toString());
        courseList.add(ct);
      }
    }

    return ResultVoUtil.success(courseList);
  }

}

